home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / Spiele / GEMSPIEL / COLTRIS / SOURCES / GRAPHIK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-17  |  11.9 KB  |  541 lines

  1. #include "cltr.h"
  2. #include <ctype.h>
  3. #include <tos.h>
  4. #include <linea.h>            /* just to read line-a-vars */
  5.  
  6. #include <image.h>
  7.  
  8. int check_recs(int x,int y,int w,int h,int *x1,int *y1,int *w1,int *h1);
  9. void redraw_play(int *message);
  10. int do_control(int flag);
  11.  
  12.  
  13. /*------------------------------------------------------------------------------
  14.  
  15.     quick-copy: schnelle kopierroutinen (nur standard ST-high artige auflösungen)
  16.  
  17. ------------------------------------------------------------------------------*/
  18.     /* variable für ass-routinen */
  19.  
  20. void copy_120(char *dest,char *source,int lines);
  21. void copy_144(char *dest,char *source,int lines);
  22. void copy_168(char *dest,char *source,int lines);
  23. void copy_160(char *dest,char *source,int lines);
  24. void copy_200(char *dest,char *source,int lines);
  25.  
  26. void (*qcopy)(char *dest,char *source,int lines);
  27. int copy_max,copy_min;
  28. Copy_Out copy_out;
  29.  
  30. static void vcopy_out(void)
  31. {
  32. int xy[8];
  33. int w;
  34.  
  35.     if ( copy_min<copy_max ) {
  36.         if ( copy_min+y_off>=screen_h || x_off>=screen_w )
  37.             return;
  38.         if ( copy_max+y_off>=screen_h )
  39.             copy_max=screen_h-y_off-1;
  40.         w=width;
  41.         if ( x_off+width>=screen_w )
  42.             w=screen_w-x_off;
  43.  
  44.         xy[0]=0;
  45.         xy[1]=copy_min;
  46.         xy[2]=w-1;
  47.         xy[3]=copy_max;
  48.         xy[4]=x_off;
  49.         xy[5]=y_off+copy_min;
  50.         xy[6]=x_off+w-1;
  51.         xy[7]=y_off+copy_max;
  52.  
  53.         if ( x_off<0 )
  54.             xy[0]-=x_off, xy[4]=0;
  55.         if ( xy[6]>=0 ) {
  56.             Vsync();
  57.             vro_cpyfm(handle,S_ONLY,xy,&buffer,&screen);
  58.         }
  59.         copy_min=buffer_height;
  60.         copy_max=0;
  61.     }
  62. }
  63.  
  64. static void qcopy_out(void)
  65. {
  66. char *source,*dest;
  67.  
  68.     if ( copy_min<copy_max ) {
  69.         if ( copy_min+y_off>=screen_h || x_off>=screen_w )
  70.             return;
  71.         if ( x_off+width>=screen_w ) {
  72.             vcopy_out();
  73.             return;
  74.         }
  75.         if ( copy_max+y_off>=screen_h )
  76.             copy_max=screen_h-y_off-1;
  77.         source=(char*)buffer_addr+(long)copy_min*buffer_width;
  78.         dest=(char*)screen_addr+(long)(copy_min+y_off)*screen_width+x_off/8;
  79.         Vsync();
  80.         qcopy(dest,source,copy_max-copy_min);
  81.         copy_min=buffer_height;
  82.         copy_max=0;
  83.     }
  84. }
  85.  
  86. static void mcopy_out(void)
  87. {
  88. int xy[8];
  89.  
  90.     if ( copy_min<copy_max ) {
  91.         xy[3]=wind[W_PLAY].handle;
  92.         xy[4]=x_off;
  93.         xy[5]=y_off+copy_min;
  94.         xy[6]=x_off+width-1;
  95.         xy[7]=y_off+copy_max;
  96.         check_recs(0,0,screen_w,screen_h,xy+4,xy+5,xy+6,xy+7);
  97.         redraw_play(xy);
  98.         copy_min=buffer_height;
  99.         copy_max=0;
  100.     }
  101.     do_control(1);
  102. }
  103.  
  104. static void init_quickcopy(void)
  105. {
  106.     linea_init();
  107.     screen_addr=(long)Logbase();
  108.     screen_width=Linea->v_lin_wr;
  109. }
  110.  
  111. void init_copy_out(void)
  112. {
  113. int w=game->block_w*game->game_width;
  114.  
  115.     quick_flag=0;
  116.     if ( !opts.graph && planes==1 ) {
  117.         switch ( w ) {
  118.           case 120:
  119.               qcopy=copy_120;
  120.           break;
  121.            case 144:
  122.               qcopy=copy_144;
  123.           break;
  124.            case 168:
  125.               qcopy=copy_168;
  126.           break;
  127.            case 160:
  128.               qcopy=copy_160;
  129.           break;
  130.            case 200:
  131.               qcopy=copy_200;
  132.           break;
  133.           default:
  134.               qcopy=0;
  135.         }
  136.         if ( qcopy ) {
  137.             quick_flag=1;
  138.             if ( !screen_addr )
  139.                 init_quickcopy();
  140.         }
  141.     }
  142.  
  143.     if ( opts.multi )
  144.         copy_out=mcopy_out;
  145.     else if ( quick_flag )
  146.         copy_out=qcopy_out;
  147.     else
  148.         copy_out=vcopy_out;
  149.  
  150.     copy_min=buffer_height;
  151.     copy_max=0;
  152. }
  153.  
  154. /*------------------------------------------------------------------------------
  155.  
  156.     copy-routine zum kopieren der blöcke in den puffer
  157.         drXX_block: kopiere monochrom direkt (blockbreite XX)
  158.         dr_block:   kopiere via vdi
  159.  
  160. ------------------------------------------------------------------------------*/
  161.  
  162. void xcopy16(void *ziel,void *quelle,int lines);
  163. void xxcopy32(void *ziel,void *quelle,int lines,long maske);
  164.  
  165. void dr16_block(int x,int y,int col)
  166. {
  167. void *source,*dest;
  168.  
  169.     x=game->x_pos[x];
  170.     y=game->y_pos[y];
  171.     source=(void*)((char*)game->bloecke.fd_addr+col*2);
  172.     dest=(void*)((char*)buffer.fd_addr+y*buffer_width+x/8);
  173.                                 /* x immer durch 16 teilbar!!! */
  174.     xcopy16(dest,source,game->bloecke.fd_h-1);
  175.  
  176.     if ( y<copy_min )
  177.         copy_min=y;
  178.     if ( y+game->block_xh>copy_max )
  179.         copy_max=y+game->block_xh;
  180. }
  181.  
  182. void dr20_block(int x,int y,int col)
  183. {
  184. void *source,*dest;
  185. static long masks[]={~0xFFFFF000l,~0x0FFFFF00l,~0x00FFFFF0l,~0x000FFFFFl};
  186.  
  187.     x=game->x_pos[x];
  188.     y=game->y_pos[y];
  189.     source=(void*)((char*)game->xbloecke[(x&15)/4].fd_addr+col*4);
  190.     dest=(void*)((char*)buffer.fd_addr+y*buffer_width+((x/8)&~1));
  191.     xxcopy32(dest,source,game->xbloecke[0].fd_h-1,masks[(x&15)/4]);
  192.  
  193.     if ( y<copy_min )
  194.         copy_min=y;
  195.     if ( y+game->block_xh>copy_max )
  196.         copy_max=y+game->block_xh;
  197. }
  198.  
  199. void dr24_block(int x,int y,int col)
  200. {
  201. void *source,*dest;
  202. static long masks[]={~0xFFFFFF00l,~0x00FFFFFFl};
  203.  
  204.     x=game->x_pos[x];
  205.     y=game->y_pos[y];
  206.     source=(void*)((char*)game->xbloecke[(x&15)/8].fd_addr+col*4);
  207.     dest=(void*)((char*)buffer.fd_addr+y*buffer_width+((x/8)&~1));
  208.     xxcopy32(dest,source,game->xbloecke[0].fd_h-1,masks[(x&15)/8]);
  209.  
  210.     if ( y<copy_min )
  211.         copy_min=y;
  212.     if ( y+game->block_xh>copy_max )
  213.         copy_max=y+game->block_xh;
  214. }
  215.  
  216. void dr_block(int x,int y,int col)
  217. {
  218. int xy[8],yy;
  219.  
  220.     xy[0]=col*game->source_width;
  221.     xy[1]=0;
  222.     xy[2]=xy[0]+game->block_xw;
  223.     xy[3]=game->block_xh;
  224.     xy[4]=game->x_pos[x];
  225.     yy=xy[5]=game->y_pos[y];
  226.     xy[6]=xy[4]+game->block_xw;
  227.     xy[7]=xy[5]+game->block_xh;
  228.     vro_cpyfm(handle,S_ONLY,xy,&game->bloecke,&buffer);
  229.     if ( yy<copy_min )
  230.         copy_min=yy;
  231.     if ( yy+game->block_xh>copy_max )
  232.         copy_max=yy+game->block_xh;
  233. }
  234.  
  235. /*
  236.     ausgabe eines blockes auf den BILDSCHIRM (kein puffer)
  237.         benutzt für
  238.             preview
  239.             statistik
  240. */
  241. void dr_vdi(int x,int y,int col,int x_off,int y_off)
  242. {
  243. int xy[8];
  244.  
  245.     xy[0]=col*game->source_width;    /* blöcke auf wortgrenze verbreitert */
  246.     xy[1]=0;
  247.     xy[2]=xy[0]+game->block_xw;
  248.     xy[3]=game->block_xh;
  249.     xy[4]=game->x_pos[x]+x_off;
  250.     xy[5]=game->y_pos[y]+y_off;
  251.     xy[6]=xy[4]+game->block_xw;
  252.     xy[7]=xy[5]+game->block_xh;
  253.     if ( game->vdi || game->block_w==16 )
  254.         vro_cpyfm(handle,S_ONLY,xy,&game->bloecke,&screen);
  255.     else
  256.         vro_cpyfm(handle,S_ONLY,xy,&game->xbloecke[0],&screen);
  257. }
  258.  
  259. /*------------------------------------------------------------------------------
  260.  
  261.     ausgabe-routinen
  262.  
  263. ------------------------------------------------------------------------------*/
  264. void clr_feld(void)
  265. {
  266.     memset((char*)buffer_addr,0,buffer_size);
  267.     redraw_play(0l);
  268.     last_score=0;
  269. }
  270.  
  271. void inv_feld(void)
  272. {
  273. int *d;
  274. long i;
  275.  
  276. #if SOUND_LEVEL>0
  277.     do_sound(S_NEWLEVEL);
  278. #endif
  279.     init_wait();
  280.     for ( i=0,d=(int*)buffer_addr; i<buffer_size/2; i++ )
  281.         *d++^=-1;
  282.     redraw_play(0l);
  283.     do_wait(50);
  284.     for ( i=0,d=(int*)buffer_addr; i<buffer_size/2; i++ )
  285.         *d++^=-1;
  286.     redraw_play(0l);
  287. }
  288.  
  289. /*------------------------------------------------------------------------------
  290.  
  291.     initialisierung der blöcke aus image-datei
  292.  
  293. ------------------------------------------------------------------------------*/
  294. static int check_blocks(MFDB *blocks)
  295. {
  296. MFDB block;
  297. int blen;
  298. int i,j;
  299. char *b;
  300. int xy[8];
  301.  
  302.     block=*blocks;
  303.     block.fd_w=blocks->fd_w/16;
  304.     block.fd_wdwidth=block.fd_w/16;
  305.     if ( block.fd_w&15 )
  306.         block.fd_wdwidth++;
  307.     blen=2*block.fd_wdwidth*block.fd_nplanes*block.fd_h;
  308.     block.fd_addr=malloc(blen);
  309.     if ( !block.fd_addr )
  310.         return -1;                /* error */
  311.     memset(block.fd_addr,0,blen);
  312.     xy[4]=0;
  313.     xy[5]=0;
  314.     xy[6]=block.fd_w-1;
  315.     xy[7]=block.fd_h-1;
  316.     for ( i=15; i>=8; i-- ) {
  317.         xy[0]=block.fd_w*i;
  318.         xy[1]=0;
  319.         xy[2]=block.fd_w*i+block.fd_w-1;
  320.         xy[3]=block.fd_h-1;
  321.         vro_cpyfm(handle,S_ONLY,xy,blocks,&block);
  322.         b=block.fd_addr;
  323.         for ( j=0; j<blen; j++ )
  324.             if ( *b++!=0 )
  325.                 return i;
  326.     }
  327.     free(block.fd_addr);
  328.     return i;
  329. }
  330.  
  331. int set_xmfdb(GAME *game,int width,int cnt)
  332. {
  333. int dx,ddx,i,j;
  334. int xy[8];
  335.  
  336.     dx=width%16;
  337.  
  338.     for ( i=ddx=0; i<cnt; i++,ddx+=dx ) {
  339.         game->xbloecke[i]=game->bloecke;
  340.         game->xbloecke[i].fd_wdwidth=32;
  341.         game->xbloecke[i].fd_w=32*16;
  342.         game->xbloecke[i].fd_addr=malloc(32*2*game->bloecke.fd_h);
  343.         if ( !game->xbloecke[i].fd_addr )
  344.             return 0;
  345.  
  346.         memset(game->xbloecke[i].fd_addr,0,32*2*game->bloecke.fd_h);
  347.  
  348.         for ( j=0; j<16; j++ ) {
  349.             xy[0]=j*game->block_w;
  350.             xy[1]=0;
  351.             xy[2]=xy[0]+game->block_xw;
  352.             xy[3]=game->block_xh;
  353.             xy[4]=j*32+ddx;
  354.             xy[5]=0;
  355.             xy[6]=xy[4]+game->block_xw;
  356.             xy[7]=game->block_xh;
  357.             vro_cpyfm(handle,S_ONLY,xy,&game->bloecke,&game->xbloecke[i]);
  358.         }
  359.     }
  360.  
  361.     game->source_width=32;
  362.     return 1;
  363. }
  364.  
  365. int init_image(GAME *game,char *name,int _argc,char **_argv)
  366. {
  367. char fname[256],xname[32],*h;
  368. MFDB pic;
  369. int i;
  370.  
  371.     game->vdi=-1;
  372.  
  373.         /* name nach kleinbuchstaben wandeln */
  374.     strcpy(xname,game->name);
  375.     for ( h=xname; *h!=0; h++ )
  376.         *h=tolower(*h);
  377.  
  378.     sprintf(fname,"%s.IMG\\%s",xname,name);
  379.     for ( i=1; i<_argc; i++ ) {
  380.         h=strrchr(_argv[i],'\\');
  381.         if ( !h )
  382.             h=_argv[i];
  383.         else
  384.             h++;
  385.         if ( tolower(*h)==*xname ) {
  386.             strcpy(fname,_argv[i]);
  387.             break;
  388.         }
  389.     }
  390.  
  391.     if ( load_img(fname,&pic)==IMG_OK ) {
  392.         if ( transform_img(&pic,planes,handle)==TRFM_OK ) {
  393.             game->bloecke=pic;
  394.             game->bloecke.fd_stand=0;
  395.  
  396.             game->block_w=game->bloecke.fd_w/16;
  397.             game->block_h=game->bloecke.fd_h;
  398.             game->block_xw=game->block_w-1;
  399.             game->block_xh=game->block_h-1;
  400.             game->last_flash=check_blocks(&game->bloecke);
  401.             if ( game->last_flash<0 ) {
  402.                 free(game->bloecke.fd_addr);
  403.                 return 0;
  404.             }
  405.             game->vdi=1;
  406.  
  407.             game->source_width=game->block_w;
  408.             game->dr_block=dr_block;
  409.  
  410.             if ( planes==1 && (game->block_w==16 || game->block_w==20 || game->block_w==24) ) {
  411.                 if ( game->block_w==16 ) {
  412.                     game->vdi=0;
  413.                     game->dr_block=dr16_block;
  414.                 }
  415.                 else if ( game->block_w==20 ) {
  416.                     if ( set_xmfdb(game,20,4) ) {
  417.                         game->vdi=0;
  418.                         game->dr_block=dr20_block;
  419.                     }
  420.                 }
  421.                 else if ( game->block_w==24 ) {
  422.                     if ( set_xmfdb(game,24,2) ) {
  423.                         game->vdi=0;
  424.                         game->dr_block=dr24_block;
  425.                     }
  426.                 }
  427.             }
  428.  
  429.             for ( i=0; i<game->game_width; i++ )
  430.                 game->x_pos[i+1]=i*game->block_w;
  431.             for ( i=0; i<game->game_height; i++ )
  432.                 game->y_pos[i+game->game_firstline]=i*game->block_h;
  433.  
  434.             return 1;
  435.         }
  436.     }
  437.     if ( pic.fd_addr )
  438.         free(pic.fd_addr);
  439.     return 0;
  440. }
  441.  
  442. static long fsel;
  443.  
  444. static int fsel_check(void)
  445. {
  446. long get_cookie(long cookie);
  447.  
  448.     if( !fsel )
  449.         fsel=get_cookie('FSEL');
  450.     return fsel ? 1 : 0;
  451. }
  452.  
  453. void change_stones(void)
  454. {
  455. char soll_path[128],path[128],name[32],*h;
  456. int but,i;
  457. int reopen_window(void);
  458.  
  459.     path[0]=Dgetdrv()+'A';
  460.     path[1]=':';
  461.     Dgetpath(path+2,0);
  462.     strcat(path,"\\");
  463.     strcat(path,game->name);
  464.     strcat(path,".IMG");
  465.     strcpy(soll_path,path);
  466.     strcat(path,"\\*.IMG");
  467.  
  468.     if ( fsel_check() || _GemParBlk.global[0]!=0x200 && _GemParBlk.global[0]>=0x130 )
  469.         fsel_exinput(path, name, &but, " select stones ");
  470.     else
  471.         fsel_input(path, name, &but);
  472.  
  473.     h=strrchr(path,'\\');
  474.     if ( h )
  475.         *h=0;
  476.  
  477.     if ( stricmp(path,soll_path) ) {
  478.         wind_update(BEG_UPDATE);
  479.         i=form_alert(1,"[1][ | stones-file must be | in subdir to coltris... | ][  Copy  |Abort]");
  480.         wind_update(END_UPDATE);
  481.         if ( i==1 ) {
  482.             int read,write;
  483.             long len;
  484.             char *puffer=malloc(4096);
  485.             if ( !puffer ) {
  486.                 wind_update(BEG_UPDATE);
  487.                 form_error(8);
  488.                 wind_update(END_UPDATE);
  489.             }
  490.             else {
  491.                  strcat(soll_path,"\\");
  492.                  strcat(soll_path,name);
  493.                  strcat(path,"\\");
  494.                  strcat(path,name);
  495.                  read=Fopen(path,0);
  496.                 if ( read<0 )
  497.                     return;
  498.                  write=Fcreate(soll_path,0);
  499.                 if ( write<0 )
  500.                     { Fclose(read); return; }
  501.                 do {
  502.                      len=Fread(read,4096l,puffer);
  503.                      Fwrite(write,len,puffer);
  504.                 } while ( len==4096l );
  505.                 Fclose(read);
  506.                 Fclose(write);
  507.                 free(puffer);
  508.             }
  509.         }
  510.         else
  511.             return;
  512.     }
  513.  
  514.     if ( but ) {
  515.       GAME temp;
  516.  
  517.         temp=*game;
  518.         temp.bloecke.fd_addr=0l;
  519.         for ( i=0; i<4; i++ )
  520.             temp.xbloecke[i].fd_addr=0l;
  521.  
  522.         if ( init_image(&temp,name,0,0l) ) {
  523.             strcpy(opts.stone_file[opts.play_mode][planes_nr],name);
  524.             free(game->bloecke.fd_addr);
  525.             for ( i=0; i<4; i++ )
  526.                 if ( game->xbloecke[i].fd_addr )
  527.                     free(game->xbloecke[i].fd_addr);
  528.  
  529.             *game=temp;
  530.             if ( !reopen_window() )
  531.                 do_exit(5);
  532.         }
  533.         else {
  534.             wind_update(BEG_UPDATE);
  535.             form_alert(1,"[1][ | Error | | loading new stones... | ][ Ok ]");
  536.             wind_update(END_UPDATE);
  537.         }
  538.     }
  539. }
  540.  
  541.